#ifndef _MY_STACK_H_
#define _MY_STACK_H_

#include <atomic>
#include <memory>

using namespace std;

template<typename T>
class my_stack {		
	public:
		void push(const T& data);
		shared_ptr<T> pop();
		~my_stack();
		
	private:
		struct node;
		
		struct countedNodePtr {
			int externalCount;
			node* ptr;
		};
		
		struct node {
			shared_ptr<T> data;
			atomic<int> internalCount;
			countedNodePtr next;
			
			node (const T& d) {
				data = make_shared<T>(d);
				internalCount = 0;
			}
		};
		
		atomic<countedNodePtr> head;
		
		void increaseHeadCount(countedNodePtr& oldCounter);
};

#include "my_stack.tcc"

#endif
